use std::time::{Instant, SystemTime};

use actix_web::{HttpResponse, ResponseError};
use actix_web::http::StatusCode;
use derive_more::Display;
use rand::{
    distributions::{Distribution, Standard},
    Rng, thread_rng,
};
use serde::export::fmt::Error;
//use std::fmt::Display;
use serde::export::Formatter;
use serde_derive::{Deserialize, Serialize};

use crate::common::ApiResult;

#[derive(Debug)]
pub enum ClassifyError {
    // 分别是code，msg，（还可以有第三方code，msg等），第三个是用来记录异常栈（比如来自哪个方法，哪行等）
    // 毕竟Rust和Java不一样，不是靠抛出异常来实现的，而是返回一个Err，Err的内容自定义，而这里ClassifyError就是自定义的异常内容
    // 所以最好把这个加上
    System(i32, String, Option<String>),
    Logic(i32, String, Option<String>),
    General(i32, String, Option<String>),
}

impl std::fmt::Display for ClassifyError {
    // TODO 生命周期也能用推断，即 '_ ？
    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
        match self {
            ClassifyError::System(code, message, trace) => {
                write!(f, "({}, {})", code, message)
            }
            ClassifyError::Logic(code, message, trace) => {
                write!(f, "({}, {})", code, message)
            }
            ClassifyError::General(code, message, trace) => {
                write!(f, "({}, {})", code, message)
            }
        }
    }
}

impl ResponseError for ClassifyError {
    fn error_response(&self) -> HttpResponse {

        // 这种情况就直接是HttpCode是200即可，和客户端约定的是根据JSON里的code字段来判断是否执行成功（是要分开，相当于底层和应用层分开）
        // TODO HTTP Code是200表示请求经过了应用层处理（即非框架级别内部的处理），然后处理结果要看code值；
        match self {
            ClassifyError::System(code, message, trace) => {
                //let a = *code;
                //let b = message.clone();
                //let c = stack.unwrap();
                // TODO 记录最高等级的日志
                eprintln!("{}, {}, {:?}", code, message, trace);
                HttpResponse::Ok().body(serde_json::to_string(&ApiResult { code: *code, message: message.clone(), timestamp: time::OffsetDateTime::now_local().timestamp() }).unwrap())
            }
            ClassifyError::Logic(code, message, trace) => {
                // TODO 记录其次等级的日志
                eprintln!("{}, {}, {:?}", code, message, trace);
                HttpResponse::Ok().body(serde_json::to_string(&ApiResult { code: *code, message: message.clone(), timestamp: time::OffsetDateTime::now_local().timestamp() }).unwrap())
            }
            ClassifyError::General(code, message, trace) => {
                // TODO 记录再其次的日志
                eprintln!("{}, {}", code, message);
                HttpResponse::Ok().body(serde_json::to_string(&ApiResult { code: *code, message: message.clone(), timestamp: time::OffsetDateTime::now_local().timestamp() }).unwrap())
            }
        }
    }
}